﻿using System.Linq;
using CID.Domain.Operations;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Persistence.Tests.Operations
{
    [TestFixture]
    class LocationPersistenceTests : BasePersistenceWithDataTests
    {
        private static void AssertAreEqual(Location expected, Location actual)
        {
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.Description, actual.Description);
            Assert.AreEqual(expected.DeploymentAgent.Id, actual.DeploymentAgent.Id);
            CollectionAssert.AreEquivalent(expected.Servers.Select(x => x.Id), actual.Servers.Select(x => x.Id));
        }

        [Test]
        public void SaveNewLocation_LocationShouldBeSaved()
        {
            var session = OpenSession();
            var newLocation = DataProvider.CreateLocation(session, InfrastructureData.DeploymentAgent1);
            session.SaveOrUpdate(newLocation);
            CleanSession(session);

            Assert.AreNotEqual(NotSavedId, newLocation.Id);
            session = OpenSession();
            var retrievedLocation = session.Get<Location>(newLocation.Id);
            AssertAreEqual(newLocation, retrievedLocation);
            CleanSession(session);
        }

        [Test]
        public void SaveModifiedLocation_ChangesShouldBeSaved()
        {
            var session = OpenSession();
            var newLocation = DataProvider.CreateLocation(session, InfrastructureData.DeploymentAgent1);
            session.SaveOrUpdate(newLocation);
            CleanSession(session);

            session = OpenSession();
            var modifiedLocation = session.Get<Location>(newLocation.Id);
            AssertAreEqual(newLocation, modifiedLocation); //Necessary to load lazy collections before the session is wiped out
            modifiedLocation.ModifyProperty(x => x.Name);
            modifiedLocation.ModifyProperty(x => x.Description);
            var deploymentAgent = Infrastructure.DataProvider.GetDeploymentAgent(session, InfrastructureData.DeploymentAgent2);
            deploymentAgent.AddLocation(modifiedLocation);
            session.SaveOrUpdate(modifiedLocation);
            CleanSession(session);

            session = OpenSession();
            var retrievedLocation = session.Get<Location>(newLocation.Id);
            AssertAreEqual(modifiedLocation, retrievedLocation);
            CleanSession(session);
        }

        [Test]
        public void DeleteLocation_LocationShouldBeDeleted()
        {
            var session = OpenSession();
            var newLocation1 = DataProvider.CreateLocation(session, InfrastructureData.DeploymentAgent1, "Another Location Name");
            var newLocation2 = DataProvider.CreateLocation(session, InfrastructureData.DeploymentAgent1);
            session.SaveOrUpdate(newLocation1);
            session.SaveOrUpdate(newLocation2);
            CleanSession(session);

            session = OpenSession();
            var retrievedLocation1 = session.Get<Location>(newLocation1.Id);
            session.Delete(retrievedLocation1);
            CleanSession(session);

            session = OpenSession();
            retrievedLocation1 = session.Get<Location>(newLocation1.Id);
            var retrievedLocation2 = session.Get<Location>(newLocation2.Id);
            Assert.IsNull(retrievedLocation1);
            Assert.IsNotNull(retrievedLocation2);
            CleanSession(session);
        }
    }
}
